
<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="8" >
        <el-row :style="'height:'+0.05*client.height+'px'">
          <div class="titleText">
            教程
          </div>
        </el-row>
        <el-row :style="'height:'+0.7*client.height+'px'">
          <el-scrollbar>
          <el-collapse v-model="tutorialActiveName" accordion>
            <el-collapse-item title="简介" name = "info">
            <div class=tutorialText>
              比赛场地的宽度为16000单位，高度为9000单位，坐标原点与最左上角的像素重合。<br/>
              玩家在每轮比赛中控制两架飞船。只要其中的任意一架飞船完成比赛，玩家即可获得胜利。<br/>
              比赛赛道由许多的检查点组成。当一架飞船按顺序通过每个检查点并返回原点时，视为该飞船完成了一圈赛道。第一位完成最后一圈赛道并回到原点的玩家获得胜利。
            </div>
            </el-collapse-item>
            <el-collapse-item title="检查点机制" name = "checkpoint">
              <div class=tutorialText>
              比赛场地中设立了N个检查点，并被编号为0……N-1。<br/>
              每个检查点可以被看作是半径为600单位的圆。只要一架飞船的中心进入了圆内，系统便判定该飞船通过了这个检查点。<br/>
              每轮比赛的检查点布置均不同。
            </div>
            </el-collapse-item>
            <el-collapse-item title="飞船运作机制" name = "pod">
              <div class=tutorialText>
                通过输出一个格式为<strong>"[目标坐标] [推动力]"</strong>的指令字符串，你就可以操纵你的飞船在场地中移动。其中推动力代表了飞船的加速度，其值必须在0-100间。<br/>
                这条指令会让你的飞船在这回合转向目标坐标并且以推动力的数值在该方向上加速。<br/>
                需要注意的是，飞船每回合的最大转向角度是18°。<br/>
                除了该指令之外，还有两条指令："BOOST"与"SHIELD"。<br/>
                <strong>BOOST指令</strong>会让你的飞船在该回合内速度大幅提升，但每局只能使用一次。之后再次使用时飞船会以默认最大加速度加速。<br/>
                以飞船中心为圆心半径400单位的区域内布满着飞船产生的力场，这意味着当两架飞船间距太小时它们便会相互碰撞。<br/>
                而<strong>SHIELD指令</strong>可以开启你的飞船的护盾，使系统在计算该飞船的碰撞事件时使用的质量值更大（更不容易被击退）。但作为代价，在接下来的三回合内飞船不能加速。<br/>
                此外，飞船可以飞出场地。
            </div>
            </el-collapse-item>
            <el-collapse-item title="系统结算机制" name = "system">
              <div class=tutorialText>
              每回合系统以如下方式计算飞船的移动：<br/>
              转向：飞船转向目标点，但转角不能超过18°。(比赛的第一轮除外)<br/>
              加速：将飞船面向方向对应的的单位矢量与加速度相乘，累加到飞船的速度矢量上。<br/>
              移动：将飞船的速度矢量加到飞船的坐标上。如果两飞船之间发生碰撞，则它们会彼此弹开。<br/>
              摩擦：将飞船当前的速度矢量乘以0.85.<br/>
              计算过程中会将飞船的速度向下取整至整数，将飞船的坐标四舍五入为整数。<br/>
              注：游戏过程中所有碰撞均为弹性碰撞。碰撞时的最小冲量为120.<br/>
              BOOST指令相当于以650的加速度加速飞船。每位玩家可使用的BOOST指令的次数由两艘飞船共享。
              SHIELD指令会将飞船的质量乘10.<br/>
              系统提供的所有的角度均为绝对角度。0°对应着正西方向，90°对应着正南方向。
              <!-- Note: You may activate debug mode in the settings panel () to view additional game data. 暂未翻译-->
            </div>
            </el-collapse-item>
            <el-collapse-item title="代码示例" name = "codeExample">
              <div class=tutorialText>
            </div>
            </el-collapse-item>
          </el-collapse></el-scrollbar>
        </el-row>
        <br>
        <el-row :style="'height:'+0.15*client.height+'px'">
          <el-card align="center" style="height: 100%">
            {{user.username}}(头像) VS {{opponent.username}}(头像)
            <br>
            <el-button type="primary" @click="dialogTableVisible = true">提交代码</el-button>
          </el-card>
        </el-row>
      </el-col>
      <el-col :span="12" >
        <el-row :style="'height:'+0.55*client.height+'px;'+'align:center;'">
          <canvas style="align:center;" id="canvas" :width="client.width*0.48" :height="client.width*0.48*9/16" >
            您的浏览器不支持，请更新
          </canvas>
        </el-row>
        <br>
        <el-row :style="'height:'+0.35*client.height+'px'">
          <el-card :style="'height:'+0.35*client.height+'px'">
            <el-scrollbar :style="'height:'+0.35*client.height+'px'">
              <h3 class="title" style="color: #ff8f16;">Standard Error Stream:</h3>
              <pre>a 19.674637 b 109.674637</pre>
              <p>&nbsp;</p>
              <h3 class="title" style="color: #ff8f16;">Standard Output Stream:</h3>
              <pre>5190 3187 100</pre>
              <h3 class="title" style="color: #ff8f16;">Standard Output Stream:</h3>
              <div class="outputLine">5398 2845 BOOST</div>
              <div class="outputLine">5398 2845 BOOST</div>
              <h3 class="title" style="color: #ff8f16;">Game information:</h3>
              <pre>Pod 1 of player <span class="nickname" style="background-color: #ff8f16;">ChenyangDu</span> boosts towards (5398, 2845)
  Pod 2 of player <span class="nickname" style="background-color: #ff8f16;">ChenyangDu</span> boosts towards (5398, 2845)
  </pre>

            </el-scrollbar>
          </el-card>
        </el-row>
      </el-col>
      <el-col :span="4" :style="'height:'+0.9*client.height+'px'">
        <el-scrollbar style="height: 100%">
          <div v-for="(item,id) in leaderBoard" :key="id">
            <el-card >
              {{id+1}}{{item.username}}
              <el-link type="danger">
                <label style="cursor:pointer;" @click="changeOpponent(item)">对战</label>
              </el-link>
            </el-card>
            <br>
          </div>
        </el-scrollbar>
      </el-col>
    </el-row>

    <el-dialog title="提交代码" :visible.sync="dialogTableVisible">
      <el-row>
        <el-col :span="20" :offset="2">
          <!-- <el-input
                  type="textarea"
                  :rows="15"
                  placeholder="请输入内容"
                  v-model="inputCode">s
          </el-input> -->
          <el-scrollbar :style ="'height:'+0.4*client.height+'px;width:'+0.85*client.height+'px;overflow-x:hidden'">
            <prism-editor class="my-editor height-200" v-model="code" :highlight="highlighter" line-numbers></prism-editor>
          </el-scrollbar>
        </el-col>
      </el-row>
      <br>
      <el-row style="align:center;">
        <el-col :span="6" :offset="2">
          <el-select v-model="language" placeholder="请选择语言">
            <el-option
                    v-for="item in options"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value">
            </el-option>
          </el-select>
        </el-col>
        <el-col :span="3" :offset="1">
          <el-button type="primary" @click="submit">提交</el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>

<script>
  import { PrismEditor } from 'vue-prism-editor';
  import 'vue-prism-editor/dist/prismeditor.min.css'; 
  import { highlight, languages } from 'prismjs/components/prism-core';
  import 'prismjs/components/prism-clike';
  import 'prismjs/components/prism-javascript';
  import 'prismjs/components/prism-python';
  import 'prismjs/components/prism-c';
  import 'prismjs/themes/prism-tomorrow.css';

  import * as can from "../components/drawCanvas";
  export default {
    name: "Plane",
    components: {
      PrismEditor,
    },
    data() {
      return {
        dialogTableVisible : false,
        user:{
          username:"",
          id:""
        },
        opponent:{
          username:"BOSS",
          id:"",
        },
        leaderBoard:this.getLeaderBoard(),
        client:{
          height:'',
          width:''
        },
        inputCode: "",
        options: [{
          value: 'C',
          label: 'C'
        }, {
          value: 'Python3',
          label: 'Python3'
        }],
        language: 'C',
        allLoaded:false,
        img_background:null,
        img_plan:null,
        GameInfo:{
          "Turns": [
            {
              "pots": {
                "6": [
                  [
                    11064,
                    7250,
                    -1.5707963267948966
                  ]
                ]
              },
              "turns": 0
            },
            {
              "pots": {
                "6": [
                  [
                    11043.089487553307,
                    7236.297793272006,
                    -1.5707963267948966
                  ]
                ]
              },
              "turns": 1
            },
            {
              "pots": {
                "6": [
                  [
                    11001.310283684814,
                    7208.920784229474,
                    -1.5707963267948966
                  ]
                ]
              },
              "turns": 2
            }
          ],
          "map": "value"
        },
        tutorialActiveName:"",
        code:"//here should be a test code"
      }
    },
    mounted() {
      this.getUser();
      let canvas = document.getElementById('canvas')
      this.client.width = `${document.documentElement.clientWidth}`
      this.client.height = this.client.width*7.5/16
      let vue = this;
      vue.img_background = new Image();
      vue.img_background.src = 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2594702193,2315377552&fm=26&gp=0.jpg'
      vue.img_background.onload = function(){
        vue.img_plan = new Image();
        vue.img_plan.src = "https://p.pstatp.com/origin/1384c00007b8d787b520c"
        vue.img_plan.onload = function () {
          vue.allLoaded = true;
          //vue.drawFrame(canvas,img_background,img_plan,0);
        }
      }
      can.test();
    },
    methods:{
      getUser(){
        let vue = this;
        let id = this.user.id
        axios.get("/user/get",{
          params:{id:localStorage.getItem("userID")}
        }).then((res)=>{
          res = res.data
          if(res.code == 200){
            vue.user = JSON.parse(res.data)
          }
        }).catch((err)=>(console.log(err)))
      },
      changeOpponent(someOne){
        this.opponent = someOne
      },
      drawInit(canvas){
        let potName = localStorage.getItem("userID")
        let vue = this;
        console.log("size",vue.client.width,vue.client.height);
        for(let turn of this.GameInfo.Turns){
          turn.pots[potName][0][0] = Math.round(turn.pots[potName][0][0]*canvas.width/16000)
          turn.pots[potName][0][1] = Math.round(turn.pots[potName][0][1]*canvas.height/9000)
        }
      },
      drawFrame(canvas,background,plane,turn){
        if(turn === 0){
          this.drawInit(canvas);
        }
        if(turn > this.GameInfo.Turns.length-2){
          return;
        }
        let vue = this;
        let ctx = canvas.getContext('2d');
        let t = 0;
        const transitionTime = 0.5,timeout = 30,
            totT = parseInt(Math.round(1000*transitionTime/timeout));
        let potName = localStorage.getItem("userID")
        let startPot = this.GameInfo.Turns[turn].pots[potName][0];
        let endPot = this.GameInfo.Turns[turn+1].pots[potName][0];
        console.log(turn,startPot,endPot)
        let deltaX = (endPot[0] - startPot[0])/totT
        let deltaY = (endPot[1] - startPot[1])/totT
        let deltaR = (endPot[2] - startPot[2])/totT

        let interval = setInterval(function () {
          ctx.save();
          ctx.clearRect(0,0,canvas.width,canvas.height)
          ctx.drawImage(background,0,0,canvas.width,canvas.height)
          vue.drawPlane(ctx,plane,startPot[0],startPot[1],startPot[2])
          startPot[0] += deltaX
          startPot[1] += deltaY
          startPot[2] += deltaR
          t++
          ctx.restore();
          if(t>=totT){
            clearInterval(interval)
            vue.drawFrame(canvas,background,plane,turn+1);
          }
        },timeout)
      },
      drawPlane(ctx,plane,x,y,rot){
        ctx.save();
        const planeSize = 100;
        let center = this.getCenter(x,y,planeSize,planeSize)
        console.log("plane",center.x,center.y)
        ctx.translate(center.x,center.y)
        ctx.rotate(rot)
        ctx.translate(-planeSize/2,-planeSize/2)
        ctx.drawImage(plane,0,0,planeSize,planeSize)
        ctx.restore();
      },
      getCenter(sx, sy, width, height){ // 返回物体的中心点
        return {
          x: sx + (width / 2),
          y: sy + (height / 2)
        };
      },
      submit(){
        let _this = this
        if(this.language === null){
          this.$notify.error({
            title: '错误',
            message: '请选择语言'
          });
          return;
        }
        axios({
          method: 'post',
          url: '/code/submit',
          data: {
            "userID":localStorage.getItem("userID"),
            "gameName":"plane",
            "language":_this.language,
            "data":_this.inputCode
          }
        }).then((res)=>{
          res = res.data
          // console.log("response",JSON.stringify(res.data[0].pots["6"][0][0]))
          // console.log("response",res.data[0].pots["6"][0][0])
          _this.dialogTableVisible = false
          _this.GameInfo.Turns = res.data
          console.log(_this.GameInfo)
          if(_this.allLoaded){
            console.log("hi")
            _this.drawFrame(document.getElementById('canvas')
                ,_this.img_background,_this.img_plan,0);
          }
        })
      },
      getLeaderBoard(){
        return new Array(20).fill({username:"王小明",id:123})
      },
      highlighter(code) {
        return Prism.highlight(code, Prism.languages.c, "c");
      }
    }
  }
</script>

<style>
  .el-scrollbar__wrap{
    overflow-x: hidden;
  }
  .titleText{
    text-align: center;
    font-family: Microsoft YaHei;
}
/* required class */
.my-editor {
  background: #ebf6f7;
  color: #241a08;

  font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
  font-size: 14px;
  line-height: 1.5;
  padding: 5px;
}

/* optional class for removing the outline */
.prism-editor__textarea:focus {
  outline: none;
}
</style>